﻿using System;
using RpcCacheClient.Interface;

namespace RpcCacheClient.Memcached
{
    public class MemcachedService : IMemcachedCache
    {
        public CacheType CacheType => CacheType.Memcached;

        private readonly MemcachedCache _Cache;
        public bool IsEnable
        {
            get => RpcCacheService.CheckIsInit(this.CacheType);
        }
        public MemcachedService()
        {
            _Cache = new MemcachedCache();
        }
        public bool Add<T>(string key, T data, TimeSpan expiresAt)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.Add(key, data, expiresAt);
        }

        public bool Add<T>(string key, T data)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.Add(key, data);
        }

        public T AddOrUpdate<T>(string key, T data, Func<T, T, T> upFunc)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.AddOrUpdate(key, data, upFunc);
        }

        public T AddOrUpdate<T>(string key, T data, Func<T, T, T> upFunc, TimeSpan expiresAt)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.AddOrUpdate(key, data, upFunc, expiresAt);
        }

        public bool CasAdd<T>(string key, T data)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.CasAdd(key, data);
        }

        public bool CasAdd<T>(string key, T data, TimeSpan expiresAt)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.CasAdd(key, data, expiresAt);
        }

        public T GetOrAdd<T>(string key, T data)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.GetOrAdd(key, data);
        }

        public T GetOrAdd<T>(string key, T data, TimeSpan expiresAt)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.GetOrAdd(key, data, expiresAt);
        }

        public bool Remove(string key)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.Remove(key);
        }

        public bool Replace<T>(string key, T data, ref ulong cas)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.Replace(key, data, ref cas);
        }

        public bool Replace<T>(string key, T data, ref ulong cas, TimeSpan expiresAt)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.Replace(key, data, ref cas, expiresAt);
        }

        public bool Replace<T>(string key, T data, TimeSpan expiresAt)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.Replace(key, data, expiresAt);
        }

        public bool Replace<T>(string key, T data)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.Replace(key, data);
        }

        public bool Set<T>(string key, T data, ref ulong cas)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.Set(key, data, ref cas);
        }

        public bool Set<T>(string key, T data, ref ulong cas, TimeSpan expiresAt)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.Set(key, data, ref cas,expiresAt);
        }

        public bool Set<T>(string key, T data)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.Set(key, data);
        }

        public bool Set<T>(string key, T data, TimeSpan expiresAt)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.Set(key, data, expiresAt);
        }

        public bool Set<T>(string key, T data, DateTime expire)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.Set(key, data, expire);
        }

        public bool TryGet<T>(string key, out T data, out ulong cas)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.TryGet(key, out data, out cas);
        }

        public bool TryGet<T>(string key, out T data)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.TryGet(key, out data);
        }

        public bool TryRemove<T>(string key, out T data)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.TryRemove(key, out data);
        }

        public bool TryRemove<T>(string key, Func<T, bool> func, out T data)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.TryRemove(key, func, out data);
        }

        public bool TryRemove<T>(string key, Func<T, bool> func)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.TryRemove(key,  func);
        }

        public T TryUpdate<T>(string key, T data, Func<T, T, T> upFunc)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.TryUpdate(key, data, upFunc);
        }

        public bool TryUpdate<T>(string key, Func<T, T> upFunc, out T data)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.TryUpdate(key, upFunc, out data);
        }

        public bool TryUpdate<T>(string key, Func<T, T> upFunc, out T data, TimeSpan expiresAt)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.TryUpdate(key, upFunc, out data, expiresAt);
        }

        public T TryUpdate<T>(string key, T data, Func<T, T, T> upFunc, TimeSpan expiresAt)
        {
            key = RpcCacheService.FormatKey(key);
            return this._Cache.TryUpdate(key, data,upFunc,expiresAt);
        }
    }
}
